package com.xucranger.ojapi.handler;

import com.alibaba.fastjson.JSON;
import com.xucranger.ojapi.anno.Mylog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

/**
 * [  操作日志记录处理,对所有Mylog注解的Controller进行操作日志监控 ]
 *
 * @author Xucranger
 * @version 1.0
 * @company Xucranger
 * @copyright (c) 2022 Xucranger. All rights reserved.
 * @date 2022.8.23
 * @since JDK1.8
 */
@Slf4j
@Aspect
@Component
public class GlobalLogHandler {
    @Pointcut("execution(* com.xucranger.ojapi.controller.*Controller.*(..)))")
    public void Makelog(){

    }

    @AfterReturning(pointcut = "Makelog()")
    public void doAfterReturning(JoinPoint joinPoint) {
        handleLog(joinPoint, null);
    }

    @AfterThrowing(value = "Makelog()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        handleLog(joinPoint, e);
    }

    protected void handleLog(final JoinPoint joinPoint, final Exception e) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Mylog operateLog = this.getAnnotationLog(joinPoint);
            if (operateLog == null) {
                return;
            }

            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            String operateMethod = className + "." + methodName;
            Object[] args = joinPoint.getArgs();
            StringBuilder sb = new StringBuilder();
            for (Object obj : args) {
                sb.append(obj.getClass().getSimpleName());
                sb.append("[");
                sb.append(JSON.toJSONString(obj));
                sb.append("]");
            }
            String params = sb.toString();
            if (e != null) {
                log.error(operateMethod+"请求失败!"+"失败原因:"+e.getMessage());
            }
            log.info(operateMethod+"请求成功!"+"请求参数:"+params);
        } catch (Exception exp) {
            log.error("保存操作日志异常:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }

    private Mylog getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Mylog classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Mylog.class);

        if (method != null) {
            return classAnnotation;
        }
        return null;
    }

}
